import json, os
from reportlab.lib.pagesizes import A4
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Image
from reportlab.lib.units import cm
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase import pdfmetrics
from reportlab.lib import colors
from PIL import Image as PILImage


# Register the font
def register_fonts(font_path):
    pdfmetrics.registerFont(TTFont('MicrosoftYaHei', font_path))

# Resize image
def resize_image(image_path, target_width_cm):
    img = PILImage.open(image_path)
    aspect_ratio = img.height / img.width
    if img.width > img.height:
        target_height_cm = target_width_cm * aspect_ratio
        target_width = target_width_cm * cm
        target_height = target_width * aspect_ratio
    else:
        target_height_cm = target_width_cm
        target_width_cm = target_height_cm / aspect_ratio
        target_width = target_width_cm * cm
        target_height = target_height_cm * cm
    return Image(image_path, width=target_width, height=target_height)


def create_main_page(json_data):
    # Register font from JSON input
    register_fonts(json_data['font_path'])
    # Resize image and insert into the table
    resized_image = resize_image(json_data['defects_dom_path'], json_data['defects_dom_width_cm'])
    main_table_data = json_data['main_table_data']
    main_table_data.insert(5, [resized_image])  # Insert image at the correct position
    # Define table styles
    main_table_element = Table(main_table_data, colWidths=[2*cm, 4*cm, 2*cm, 4*cm, 2*cm, 4*cm])
    main_table_element.setStyle(TableStyle([
        ('SPAN', (0, 0), (-1, 0)),  # 合并第一行所有列
        ('LEADING', (0, 0), (-1, 0), 22), # 设置第一行的行高为22
        ('ALIGN', (0, 0), (-1, 0), 'CENTER'), # 第一行文字居中
        ('FONTSIZE', (0, 0), (-1, 0), 18), # 第一行文字字号18
        ('BACKGROUND', (0, 0), (-1, 0), colors.lightgreen), # 第一行为表头 背景色为浅绿
        ('SPAN', (1, 1), (3, 1)),  # 合并第2行2 3 4列
        ('SPAN', (1, 2), (3, 2)),  # 合并第3行2 3 4列
        ('SPAN', (0, 5), (-1, 5)),  # 合并第6行所有列 用于封装图片
        ('ALIGN', (0, 5), (-1, 5), 'CENTER'), # 图片显示居中
        ('VALIGN', (0, 5), (-1, 5), 'MIDDLE'), # 图片显示行高度居中
        ('LEADING', (0, 5), (-1, 5), 550), # 设置第5行 图片部分行高500
        ('SPAN', (0, 6), (-1, 6)),  # 合并第6行所有列 用于显示说明
        ('LEADING', (0, 6), (-1, 6), 15), # 说明部分 行高为13
        ('BACKGROUND', (1, 1), (-1, -1), colors.white), # 除了第1行其他的背景都为白色
        ('TEXTCOLOR', (0, 0), (-1, -1), colors.black), # 所有的字的颜色为黑色
        ('LEADING', (0, 1), (-1, 3), 13), # 除了第1行至第4行 行高为12
        ('ALIGN', (0, 1), (-1, 4), 'LEFT'), # 除了第1行 他行的行为左对齐
        ('ALIGN', (0, 6), (-1, -1), 'LEFT'), # 除了第1行 他行的行为左对齐
        ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), # 所有行高度居中
        ('FONTNAME', (0, 0), (-1, -1), 'MicrosoftYaHei'), # 所有字体为微软雅黑
        ('GRID', (0, 0), (-1, -1), 1, colors.black), # 绘制所有框线
        ('LEFTPADDING', (0, 0), (-1, -1), 5), # 所有行左侧留白5
        ('BOTTOMPADDING', (0, 0), (-1, -1), 5), # 所有行底部留白5
        ('TOPPADDING', (0, 0), (-1, -1), 5), # 所有行顶侧留白5
        ('FONTSIZE', (0, 1), (-1, -1), 10), # 除了第1行其他的字号为10
    ]))
    return main_table_element

# Convert JSON paths to Python paths
def convert_path(json_path):
    return json_path.replace("/", os.sep)

def create_sub_page(json_data):
    # Register font from JSON input
    register_fonts(json_data['font_path'])
    image_width_cm = 14.5
    # 获取sub page的数量
    sub_table_page = []
    for element in json_data['sub_table_data']:
        # Copy the element to modify it
        sub_element = element.copy()
        del sub_element[-1]
        del sub_element[-1]
        # Process the 5th and 6th elements (paths)
        if len(element) >= 5:
            # Convert and resize the images at positions 5 and 6
            for i in [4, 5]:
                if os.path.exists(convert_path(element[i][0])):
                    sub_element.append([resize_image(convert_path(element[i][0]), image_width_cm)])
                else:
                    print(f"Image at {convert_path(sub_element[i][0])} not found.")
            sub_table = Table(sub_element, colWidths=[2*cm, 4*cm, 2*cm, 4*cm, 2*cm, 4*cm])
            sub_table.setStyle(TableStyle([
                ('SPAN', (0, 0), (-1, 0)),  # 合并第一行所有列
                ('LEADING', (0, 0), (-1, 0), 22), # 设置第一行的行高为22
                ('ALIGN', (0, 0), (-1, 0), 'CENTER'), # 第一行文字居中
                ('FONTSIZE', (0, 0), (-1, 0), 18), # 第一行文字字号18
                ('BACKGROUND', (0, 0), (-1, 0), colors.lightgreen), # 第一行为表头 背景色为浅绿
                ('SPAN', (1, 1), (3, 1)),  # 合并第2行2 3 4列
                ('SPAN', (1, 2), (3, 2)),  # 合并第3行2 3 4列
                ('SPAN', (1, 3), (3, 3)),  # 合并第4行2 3 4列
                ('SPAN', (0, 4), (-1, 4)),  # 合并第5行所有列 用于封装图片
                ('SPAN', (0, 5), (-1, 5)),  # 合并第6行所有列 用于封装图片
                ('ALIGN', (0, 4), (-1, 5), 'CENTER'), # 图片显示居中
                ('LEADING', (0, 4), (-1, 4), 330), # 设置第5行 图片部分行高320
                ('LEADING', (0, 5), (-1, 5), 310), # 设置第5行 图片部分行高300
                ('BACKGROUND', (1, 1), (-1, -1), colors.white), # 除了第1行其他的背景都为白色
                ('TEXTCOLOR', (0, 0), (-1, -1), colors.black), # 所有的字的颜色为黑色
                ('LEADING', (0, 1), (-1, 3), 13), # 除了第1行至第4行 行高为12
                ('ALIGN', (0, 1), (-1, 3), 'LEFT'), # 除了第1行 他行的行为左对齐
                ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), # 所有行高度居中
                ('FONTNAME', (0, 0), (-1, -1), 'MicrosoftYaHei'), # 所有字体为微软雅黑
                ('GRID', (0, 0), (-1, -1), 1, colors.black), # 绘制所有框线
                ('LEFTPADDING', (0, 0), (-1, -1), 5), # 所有行左侧留白5
                ('BOTTOMPADDING', (0, 0), (-1, -1), 5), # 所有行底部留白5
                ('TOPPADDING', (0, 0), (-1, -1), 5), # 所有行顶侧留白5
                ('FONTSIZE', (0, 1), (-1, -1), 10), # 除了第1行其他的字号为10
            ]))
        sub_table_page.append(sub_table)
    return sub_table_page

# Load data from JSON file and generate PDF
def generate_report_from_json(json_file):
    with open(json_file, 'r', encoding='utf-8') as f:
        json_data = json.load(f)
    # Register font from JSON input
    register_fonts(json_data['font_path'])
    # Create PDF file, top margin set to 1 cm
    pdf = SimpleDocTemplate(json_data['report_path'], pagesize=A4, topMargin=1 * cm, bottomMargin=1 * cm)
    # 分别生产主页和内页
    main_table_element = create_main_page(json_data)
    sub_table_elements = create_sub_page(json_data)
    # 拼接PDF内容
    pdf_elements = []
    pdf_elements.append(main_table_element)
    # 将每个子表单元素逐个添加到 pdf_elements 中
    for sub_table in sub_table_elements:
        pdf_elements.append(sub_table)
    # Build PDF
    pdf.build(pdf_elements)


# Example usage
generate_report_from_json('report_data.json')
